﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using CRMAdminDashboard.CrmSvc;
using CRMAdminDashboard.Properties;

namespace CRMAdminDashboard
{
    /// <summary>
    /// Represents userquery.querytype Property
    /// </summary>
    public class SavedQueryType
    {

        /// <summary>
        /// Actual field value for QueryType in userquery
        /// </summary>
        public enum QueryTypeFieldValue
        {
            ABF = 512,
            ADS = 1,
            LUV = 64,
            MAS = 32,
            MAV = 0,
            MWS = 1024,
            OFF = 16,
            OLF = 256,
            OTH = 2048,
            QFS = 4,
            REP = 8,
            SMA = 128,
            SUG = 2,
            Invalid = -1
        };

        /// <summary>
        /// Extended QueryType value, including Active/Inactive and MAV. Used for bit masking.
        /// </summary>
        public enum QueryTypeBitValue
        {
            ABF = QueryTypeFieldValue.ABF,
            ADS = QueryTypeFieldValue.ADS,
            LUV = QueryTypeFieldValue.LUV,
            MAS = QueryTypeFieldValue.MAS,
            MAV = 4096,
            MWS = QueryTypeFieldValue.MWS,
            OFF = QueryTypeFieldValue.OFF,
            OLF = QueryTypeFieldValue.OLF,
            OTH = QueryTypeFieldValue.OTH,
            QFS = QueryTypeFieldValue.QFS,
            REP = QueryTypeFieldValue.REP,
            SMA = QueryTypeFieldValue.SMA,
            SUG = QueryTypeFieldValue.SUG,
            Active = 8192,
            Inactive = 16384
        };

        #region Fields

        /// <summary>
        /// Mnemonic code by query type
        /// </summary>
        private static Dictionary<uint, string> _mnemonicThreeChar;

        #endregion

        #region Properties

        /// <summary>
        /// Query Type (used to save it in the settings)
        /// </summary>
        public uint QueryTypeBit { get; set; }

        /// <summary>
        /// Query Type (used to filter actual CRM queries)
        /// </summary>
        public uint QueryTypeField { get; set; }

        /// <summary>
        /// Display Value
        /// </summary>
        public string DisplayValue { get; set; }

        /// <summary>
        /// Description
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// Mnemonic code by query type
        /// </summary>
        public static Dictionary<uint, string> MnemonicThreeChar
        {
            get
            {
                return _mnemonicThreeChar;
            }
        }

        #endregion

        #region Entry Points

        /// <summary>
        /// This will make the list box entry look nice
        /// </summary>
        public override string ToString()
        {
            if (MnemonicThreeChar.ContainsKey(this.QueryTypeField))
            {
                return this.DisplayValue + " (" + MnemonicThreeChar[this.QueryTypeField] + ")";
            }
            else
            {
                return this.DisplayValue;
            }
        }

        /// <summary>
        /// Load all possible values in a checked list. Check them appropriately.
        /// </summary>
        /// <param name="selectedQueryTypes"> A combination of the selected query types. Note that in selectedQueryTypes
        /// "MainApplicationView" is represented by 4096 instead than 0.</param>
        public static void LoadList(CheckedListBox list, uint selectedQueryTypes)
        {
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.ABF, QueryTypeBitValue.ABF, "Address Book Filters", "Specifies an address book filter"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.ADS, QueryTypeBitValue.ADS, "Advanced Search", "Specifies an advanced search"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.LUV, QueryTypeBitValue.LUV, "Lookup View", "Specifies a lookup view"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.MAV, QueryTypeBitValue.MAV, "Main Application View", "Specifies the main application view"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.MWS, QueryTypeBitValue.MWS, "Main Application w/o Subject", "Specifies the main application view without a subject"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.MAS, QueryTypeBitValue.MAS, "Marketing Automation Search", "Specifies the marketing automation query"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.OFF, QueryTypeBitValue.OFF, "Offline Filters", "Specifies an offline Microsoft Dynamics CRM for Microsoft Office Outlook filter query"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.OTH, QueryTypeBitValue.OTH, "Other", "Specifies a saved query"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.OLF, QueryTypeBitValue.OLF, "Outlook Filters", "Specifies a Microsoft Dynamics CRM for Outlook filter query"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.QFS, QueryTypeBitValue.QFS, "Quick Find Search", "Specifies a quick find query"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.SMA, QueryTypeBitValue.SMA, "Svc Mgmnt Appointment Book", "Specifies the service management appointment book view"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.SUG, QueryTypeBitValue.SUG, "Sub Grid", "Specifies a sub-grid"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.REP, QueryTypeBitValue.REP, "Reporting", "Specifies a reporting query"));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.Invalid, QueryTypeBitValue.Active, "-- Filter Active Views", ""));
            list.Items.Add(new SavedQueryType(QueryTypeFieldValue.Invalid, QueryTypeBitValue.Inactive, "-- Filter Inactive Views", ""));

            for (int idx = 0; idx < list.Items.Count; idx++)
            {
                SavedQueryType sq = (SavedQueryType)list.Items[idx];
                if ((sq.QueryTypeBit & selectedQueryTypes) != 0)
                {
                    list.SetItemChecked(idx, true);
                }
            }
        }

        /// <summary>
        /// Update the selected query combination according to a check event.
        /// </summary>
        public static uint CheckStatusChanged(uint selectedQueryTypes, SavedQueryType savedQueryType, CheckState checkState)
        {
            if (checkState == CheckState.Checked)
            {
                selectedQueryTypes |= savedQueryType.QueryTypeBit;
            }
            else
            {
                selectedQueryTypes &= (uint)~savedQueryType.QueryTypeBit;
            }

            return selectedQueryTypes;
        }

        /// <summary>
        /// Checks whether a query should be displayed, based on the selected query types.
        /// </summary>
        public static bool IsQuerySelected(UserQuery uq, uint selectedQueryTypes)
        {
            bool selected = false;

            if (uq.QueryType == (int)QueryTypeFieldValue.MAV)
            {
                selected = ((uint)QueryTypeBitValue.MAV & selectedQueryTypes) != 0;
            }
            else
            {
                selected = (uq.QueryType & selectedQueryTypes) != 0;
            }

            if (selected)
            {
                if (uq.StateCode == UserQueryState.Active)
                {
                    selected = ((uint)QueryTypeBitValue.Active & selectedQueryTypes) != 0;
                }
                else
                {
                    selected = ((uint)QueryTypeBitValue.Inactive & selectedQueryTypes) != 0;
                }
            }

            return selected;
        }

        #endregion

        #region Local Methods

        /// <summary>
        /// Static initializer
        /// </summary>
        static SavedQueryType()
        {
            _mnemonicThreeChar = new Dictionary<uint, string>();
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.ABF, "ABF");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.ADS, "ADS");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.LUV, "LUV");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.MAV, "MAV");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.MWS, "MWS");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.MAS, "MAS");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.OFF, "OFF");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.OLF, "OLF");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.QFS, "QFS");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.REP, "REP");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.OTH, "OTH");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.SMA, "SMA");
            _mnemonicThreeChar.Add((uint)QueryTypeFieldValue.SUG, "SUG");
        }

        /// <summary>
        /// default ctor
        /// </summary>
        private SavedQueryType(QueryTypeFieldValue typeValue, QueryTypeBitValue bitValue, string display, string description)
        {
            this.QueryTypeField = (uint)typeValue;
            this.QueryTypeBit = (uint)bitValue;
            this.DisplayValue = display;
            this.Description = description;
        }

        #endregion

    }
}
